package com.alvis.media.service.impl;

import com.alvis.media.domain.VideoInfo;
import com.alvis.media.domain.VideoPlay;
import com.alvis.media.repository.VideoInfoMapper;
import com.alvis.media.repository.VideoPlayMapper;
import com.alvis.media.service.VideoInfoService;
import com.alvis.media.utility.DateTimeUtil;
import com.alvis.media.utility.UserCFUtil;
import com.alvis.media.viewmodel.video.VideoPageRequestVM;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class VideoInfoServiceImpl extends BaseServiceImpl<VideoInfo> implements VideoInfoService {
    private final VideoInfoMapper videoInfoMapper;

    private final VideoPlayMapper videoPlayMapper;

    public VideoInfoServiceImpl(VideoInfoMapper videoInfoMapper, VideoPlayMapper videoPlayMapper) {
        super(videoInfoMapper);
        this.videoInfoMapper = videoInfoMapper;
        this.videoPlayMapper = videoPlayMapper;
    }

    /**
     * 查询本月新增视频个数
     */
    @Override
    public int selectNewVideoCount(VideoInfo videoInfo) {
        // 当月的用户新增视频数量
        // 封装查询条件
        videoInfo.setCreateTime(DateTimeUtil.getMonthStartDay());
        // 调用DAO并返回
        return videoInfoMapper.selectNewVideoCount(videoInfo);
    }

    @Override
    public VideoInfo selectByVideoName(String name) {
        return videoInfoMapper.selectByVideoName(name);
    }

    /*
     修改视频信息
     */
    @Override
    public void updateVideoInfo(VideoInfo videoInfo) {
        videoInfoMapper.updateByPrimaryKeySelective(videoInfo);
    }

    /**
     * 用户属性分析 -- 分析
     */
    @Override
    public List<VideoInfo> userAnalysis(Integer recommendUserId) {
        List<VideoInfo> result = new ArrayList<>();

        // 和该推荐用户的播放记录有交集的用户的播放记录
        // 第一步查找recommendUserId的播放列表 userid
        // 要求推荐的用户播放的视频id列表
        List<Integer> recommendVideoIdPlayList = getPlayVideoIdListByUserId(recommendUserId);
        if (CollectionUtils.isEmpty(recommendVideoIdPlayList)) {
            return videoInfoMapper.selectHotVideoList();
        }

        Set<Integer> relationUserIdList = new HashSet<>();
        // 遍历recommendVideoIdPlayList 去查找播放过这些视频的用户
        for (Integer videoId : recommendVideoIdPlayList) {
            VideoPlay filter = new VideoPlay();

            filter.setVideoId(videoId);
            List<VideoPlay> otherUserPlayList = videoPlayMapper.selectVideoPlayInfo(filter);

            if (CollectionUtils.isEmpty(otherUserPlayList)) {
                continue;
            }
            relationUserIdList.addAll(otherUserPlayList.stream()
                    .map(VideoPlay::getUserId).collect(Collectors.toSet()));
        }

        // 和该推荐用户的播放记录有交集的用户的播放记录。
        Map<Integer, List<Integer>> playList = new HashMap<>();
        playList.put(recommendUserId, recommendVideoIdPlayList);

        for (Integer userId : relationUserIdList) {
            if (userId.equals(recommendUserId)) {
                continue;
            }

            // 要求推荐的用户播放的视频id列表
            playList.put(userId, getPlayVideoIdListByUserId(userId));
        }

        List<Integer> recommendVideoIdList = UserCFUtil.getRecommendationVideoList(playList, recommendUserId);

        // 如果没有可推荐的
        if (CollectionUtils.isEmpty(recommendVideoIdList)) {
            // 最热视频列表查询（取前3个最热视频）
            return videoInfoMapper.selectHotVideoList();
        }

        for (Integer videoId : recommendVideoIdList) {
            result.add(videoInfoMapper.selectByPrimaryKey(videoId));
        }
        return result;
    }


    /**
     * 根据用户ID查询该用户的视频播放列表
     */
    private List<Integer> getPlayVideoIdListByUserId(Integer userId) {
        VideoPlay filter = new VideoPlay();
        filter.setUserId(userId);
        List<VideoPlay> recommendUserPlayList = videoPlayMapper.selectVideoPlayInfo(filter);

        // 如果没有播放列表，则没有推荐产品
        if (CollectionUtils.isEmpty(recommendUserPlayList)) {
            return new ArrayList<>();
        }

        // 要求推荐的用户播放的视频id列表

        return recommendUserPlayList.stream()
                .map(VideoPlay::getVideoId).collect(Collectors.toList());
    }


    /**
     * 添加视频播放
     */
    @Override
    public int insertVideoPlay(String videoRealUrl, Integer userId) {
        // TODO
        // step1 组装数据
        VideoPlay videoPlay = new VideoPlay();
        videoPlay.setUserId(userId);

        // 根据videoRealUrl获取videoId
        videoPlay.setVideoId(videoInfoMapper.selectVideoIdBydUrl(videoRealUrl));

        // 视频播放列表查询查询
        List<VideoPlay> videoPlayListDb = videoPlayMapper.selectVideoPlayInfo(videoPlay);
        videoPlay.setLastPlayTime(new Date());

        // 注意CollectionUtils的包不要导错
        if (CollectionUtils.isEmpty(videoPlayListDb)) {
            // insert 如果数据库中有播放次数则做 视频播放 新增操作
            videoPlay.setPlayTimes(1);
            videoPlayMapper.insertSelective(videoPlay);
        } else {
            // update 如果数据库中有播放次数则做 视频播放 修改操作
            VideoPlay videoPlayDb = videoPlayListDb.get(0);
            videoPlay.setPlayTimes(videoPlayDb.getPlayTimes() + 1);
            videoPlayMapper.updateByPrimaryKeySelective(videoPlay);
        }

        // 往t_video_paly这表insert一条数据或者update.
        return 0;
    }

    @Override
    public int insertByFilter(VideoInfo videoInfo) {
        videoInfo.setLastModifyTime(new Date());
        videoInfo.setCreateTime(new Date());
        return baseMapper.insertSelective(videoInfo);
    }

    /**
     * 视频列表分页查询
     */
    @Override
    public PageInfo<VideoInfo> findVideoInfoPage(VideoPageRequestVM requestVM) {
        return PageHelper.startPage(requestVM.getPageIndex(), requestVM.getPageSize(), "video_id desc").doSelectPageInfo(() ->
                videoInfoMapper.selectVideoPage(requestVM)
        );
    }

}
